package myJs.components

import japgolly.scalajs.react.MonocleReact._
import japgolly.scalajs.react._
import japgolly.scalajs.react.component.Scala.BackendScope
import japgolly.scalajs.react.extra.StateSnapshot
import japgolly.scalajs.react.vdom.all._
import monocle.Lens
import monocle.macros.Lenses
import myJs.myPkg.jquery._

import scala.collection.immutable.SeqMap

/**
 * Created by yz on 3/11/2020
 */
object DiagnoseComponent {

  @Lenses
  case class State(diagnoseIsExec: String, rfTop: String, svmTop: String, borutaAfterTopN: String, execCv: String,
                   seed: String, k: String)

  object State {

    def init = {
      State(diagnoseIsExec = "yes", rfTop = "10", svmTop = "10", borutaAfterTopN = "3", execCv = "yes", seed = "1234",
        k = "10")
    }

  }

  class Backend(bs: BackendScope[Unit, State]) {

    val fieldNames = List()

    def didMount(s: State): Callback = {
      Callback {
        fieldNames.foreach { fieldName =>
        }
      }
    }

    def didUpdate(preS: State, curS: State): Callback = {
      Callback {

      }
    }

    def unmount: Callback = {
      Callback {
        fieldNames.foreach { fieldName =>
        }
      }
    }

    def render(s: State) = {

      implicit class MyLens[T](lens: Lens[State, T]) {

        def zoomL(implicit r: Reusability[T]) = {
          StateSnapshot.withReuse.zoomL(lens).prepareVia(bs).apply(s)
        }
      }

      val optionMap = SeqMap("yes" -> "yes", "no" -> "no")
      val kMap = SeqMap("3" -> "3", "7" -> "7", "10" -> "10")
      val show = (s.execCv == "yes")
      val borutaAfterTopNInfo =
        s"""
           |Boruta筛选后，Decision判定为“confirmed“的变量是Boruta认为合适的Biomarker，但是由于部分项目样本数较少，因此需要再进行筛选，提取出其中前n个代谢物作为Biomarker参与后面的建模预测。
           |<br>
           |<br>
           |同时，若Boruta筛选后，没有符合要求的代谢物，会强制提取Top n进入后续的建模预测。
           |""".stripMargin
      val rfTopInfo =
        s"""
           |随机森林计算后，取重要性（平均基尼指数下降%）前n的差异代谢物参与后面的marker筛选
           |""".stripMargin
      val svmTopInfo =
        s"""
           |SVM计算后，取重要性（RFE）前n的差异代谢物参与后面的marker筛选
           |""".stripMargin
      val diagnoseIsExec = (s.diagnoseIsExec == "yes")

      div(
        SelectInlineComponent.Props(State.diagnoseIsExec.zoomL, label = "是否执行诊断分析", name = "diagnoseIsExec",
          optionMap = optionMap, labelWidth = 2, inputWidth = 3).render,
        div((display := "none").unless(diagnoseIsExec),
          div(`class` := "form-group",
            InputInlineWithLabelComponent.Props(State.rfTop.zoomL, label = "RandomForest top n",
              name = "rfTop", questionInfo = rfTopInfo).render,
            InputInlineWithLabelComponent.Props(State.svmTop.zoomL, label = "SVM top n",
              name = "svmTop", questionInfo = svmTopInfo).render
          ),
          div(`class` := "form-group",
            InputInlineWithLabelComponent.Props(State.borutaAfterTopN.zoomL, label = "Boruta执行后top n",
              name = "borutaAfterTopN", questionInfo = borutaAfterTopNInfo).render,
          ),
          SelectInlineComponent.Props(State.execCv.zoomL, label = "运行Cross-Validation", name = "execCv",
            optionMap = optionMap, labelWidth = 2, inputWidth = 3).render,
          div(`class` := "form-group", (display := s"none").when(!show),
            InputInlineWithLabelComponent.Props(State.seed.zoomL, label = "Seed",
              name = "seed").render,
            SelectInlineWithLabelComponent.Props(State.k.zoomL, label = "K-folds",
              name = "k", optionMap = kMap).render,
          )
        )
      )
    }

  }

  val Component = ScalaComponent.builder[Unit].initialState(State.init).renderBackend[Backend].
    componentDidMount(x => x.backend.didMount(x.state)).componentWillUnmount(_.backend.unmount).
    componentDidUpdate(x => x.backend.didUpdate(x.prevState, x.currentState)).
    build

}



